cmake_minimum_required(VERSION 3.10)
project(hft_system VERSION 1.0 LANGUAGES CXX)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# 设置输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

# 添加编译选项
if(MSVC)
    add_compile_options(/W4 /WX)
else()
    add_compile_options(-Wall -Wextra -Werror)
endif()

# 生成构建日期和时间
string(TIMESTAMP BUILD_DATE "%Y-%m-%d" UTC)
string(TIMESTAMP BUILD_TIME "%H:%M:%S" UTC)

# 配置版本信息
configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/include/version.h.in
    ${CMAKE_CURRENT_BINARY_DIR}/include/version.h
    @ONLY
)

# 严格检查Boost路径
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/third_party/boost)
    message(FATAL_ERROR "Boost directory not found in third_party")
endif()

# 使用Boost头文件模式
set(BOOST_INCLUDEDIR ${CMAKE_SOURCE_DIR}/third_party/boost)
include_directories(${BOOST_INCLUDEDIR})

# 对于header-only组件
add_definitions(-DBOOST_ALL_NO_LIB -DBOOST_ERROR_CODE_HEADER_ONLY -DBOOST_SYSTEM_NO_DEPRECATED)

# 设置项目包含路径
include_directories(
    ${CMAKE_SOURCE_DIR}/include
    ${CMAKE_SOURCE_DIR}/include/backtest
    ${CMAKE_SOURCE_DIR}/include/config
    ${CMAKE_SOURCE_DIR}/include/core
    ${CMAKE_SOURCE_DIR}/include/execution
    ${CMAKE_SOURCE_DIR}/include/interface
    ${CMAKE_SOURCE_DIR}/include/market_data
    ${CMAKE_SOURCE_DIR}/include/risk
    ${CMAKE_SOURCE_DIR}/include/strategy
    ${CMAKE_SOURCE_DIR}/include/utils
    ${CMAKE_SOURCE_DIR}/third_party
    ${CMAKE_SOURCE_DIR}/third_party/boost
    ${CMAKE_SOURCE_DIR}/third_party/nlohmann
    ${CMAKE_SOURCE_DIR}/third_party/googletest
    ${CMAKE_SOURCE_DIR}/third_party/spdlog
)

# 添加CTP头文件路径
if(WIN32)
    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/ctp/windows64)
else()
    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/ctp/linux64)
endif()

# 严格检查nlohmann_json路径
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/third_party/nlohmann)
    message(FATAL_ERROR "nlohmann_json directory not found in third_party")
endif()

# 设置伪目标用于链接
add_library(boost_filesystem INTERFACE)
add_library(boost_system INTERFACE)
add_library(nlohmann_json INTERFACE)

# 添加包含目录
target_include_directories(boost_filesystem INTERFACE ${CMAKE_SOURCE_DIR}/third_party/boost)
target_include_directories(boost_system INTERFACE ${CMAKE_SOURCE_DIR}/third_party/boost)
target_include_directories(nlohmann_json INTERFACE ${CMAKE_SOURCE_DIR}/third_party/nlohmann)

# 处理性能优化选项
option(HFT_ENABLE_PERF_OPT "Enable performance optimizations" ON)
option(HFT_ENABLE_AVX "Enable AVX instructions" ON)
option(HFT_ENABLE_SSE "Enable SSE instructions" ON)
option(HFT_ENABLE_MEMORY_POOL "Enable memory pool" ON)

if(HFT_ENABLE_PERF_OPT)
    if(MSVC)
        add_compile_options(/O2 /fp:fast /GL)
        add_link_options(/LTCG)
    else()
        add_compile_options(-O3 -ffast-math -flto)
        add_link_options(-flto)
    endif()
    add_definitions(-DHFT_PERF_OPT)
endif()

if(HFT_ENABLE_AVX)
    if(MSVC)
        add_compile_options(/arch:AVX2)
    else()
        add_compile_options(-mavx2 -mfma)
    endif()
    add_definitions(-DHFT_AVX)
endif()

if(HFT_ENABLE_SSE)
    if(MSVC)
        add_compile_options(/arch:SSE4.2)
    else()
        add_compile_options(-msse4.2)
    endif()
    add_definitions(-DHFT_SSE)
endif()

if(HFT_ENABLE_MEMORY_POOL)
    add_definitions(-DHFT_MEMORY_POOL)
endif()

# 检测CPU特性
include(CheckCXXSourceRuns)
check_cxx_source_runs("
    #include <immintrin.h>
    int main() {
        __m256d v = _mm256_setzero_pd();
        return 0;
    }
" HAS_AVX)

check_cxx_source_runs("
    #include <nmmintrin.h>
    int main() {
        __m128d v = _mm_setzero_pd();
        return 0;
    }
" HAS_SSE4_2)

if(HAS_AVX)
    message(STATUS "AVX support detected")
else()
    message(WARNING "AVX not supported, falling back to SSE")
    set(HFT_ENABLE_AVX OFF)
endif()

if(HAS_SSE4_2)
    message(STATUS "SSE4.2 support detected")
else()
    message(WARNING "SSE4.2 not supported, using scalar operations")
    set(HFT_ENABLE_SSE OFF)
endif()

# 检测操作系统
if(WIN32)
    set(CTP_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/windows64)
    # 支持多种可能的CTP库文件名
    set(CTP_LIB_POSSIBILITIES 
        thostmduserapi_se.lib thostmduserapi_se.lib
        thosttraderapi_se.lib thosttraderapi_se.lib
    )
    
    set(CTP_DLL_POSSIBILITIES
        thostmduserapi_se.dll thostmduserapi_se.dll
        thosttraderapi_se.dll thosttraderapi_se.dll
    )

    # 查找实际存在的库文件
    foreach(lib ${CTP_LIB_POSSIBILITIES})
        if(EXISTS "${CTP_LIB_DIR}/${lib}")
            list(APPEND CTP_LIBS "${CTP_LIB_DIR}/${lib}")
        endif()
    endforeach()

    foreach(dll ${CTP_DLL_POSSIBILITIES})
        if(EXISTS "${CTP_LIB_DIR}/${dll}")
            list(APPEND CTP_DLLS "${CTP_LIB_DIR}/${dll}")
        endif()
    endforeach()
    add_definitions(-DWIN32 -D_WINDOWS)
else()
    set(CTP_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/linux64)
    set(CTP_LIBS 
        ${CTP_LIB_DIR}/libthostmduserapi_se.so
        ${CTP_LIB_DIR}/libthosttraderapi_se.so
    )
    add_definitions(-DLINUX)
endif()


# 验证CTP库路径和文件
if(NOT EXISTS ${CTP_LIB_DIR})
    message(FATAL_ERROR "CTP library directory not found: ${CTP_LIB_DIR}")
endif()

foreach(CTP_LIB ${CTP_LIBS})
    if(NOT EXISTS ${CTP_LIB})
        message(FATAL_ERROR "CTP library file not found: ${CTP_LIB}")
    endif()
endforeach()

if(WIN32)
    foreach(CTP_DLL ${CTP_DLLS})
        if(NOT EXISTS ${CTP_DLL})
            message(FATAL_ERROR "CTP DLL file not found: ${CTP_DLL}")
        endif()
    endforeach()
endif()

# 添加子目录
add_subdirectory(src)

#include(clang-tidy.cmake) # 增加
#rocbuild_apply_clang_tidy(clang-tidy-18 main) # 增加


# 严格检查spdlog路径
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/third_party/spdlog)
    message(FATAL_ERROR "spdlog directory not found in third_party")
endif()

# 添加spdlog头文件路径(header-only模式)
include_directories(${CMAKE_SOURCE_DIR}/third_party/spdlog)

# 严格检查googletest路径
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/third_party/googletest/googletest)
    message(FATAL_ERROR "googletest directory not found in third_party")
endif()

# 使用本地third_party下的googletest
add_subdirectory(third_party/googletest/googletest)

# 启用测试
enable_testing()

# 添加测试子目录
if(EXISTS ${CMAKE_SOURCE_DIR}/tests)
    add_subdirectory(tests)
else()
    message(WARNING "tests directory not found, skipping...")
endif()

# 复制配置文件和依赖库到输出目录
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/config DESTINATION ${CMAKE_BINARY_DIR}/bin)
if(WIN32)
    file(GLOB CTP_DLLS "${CTP_LIB_DIR}/*.dll")
    file(COPY ${CTP_DLLS} DESTINATION ${CMAKE_BINARY_DIR}/bin)
else()
    file(GLOB CTP_SOS "${CTP_LIB_DIR}/*.so")
    file(COPY ${CTP_SOS} DESTINATION ${CMAKE_BINARY_DIR}/bin)
endif()

# 安装规则
install(DIRECTORY include/ 
    DESTINATION include/hft_system
    FILES_MATCHING PATTERN "*.h"
)

install(DIRECTORY config/ 
    DESTINATION etc/hft_system
    FILES_MATCHING PATTERN "*.json" PATTERN "*.ini"
)

if(WIN32)
    install(FILES ${CTP_DLLS} DESTINATION bin)
else()
    install(FILES ${CTP_SOS} DESTINATION lib)
endif()

# 添加文档目标
find_package(Doxygen)
if(DOXYGEN_FOUND)
    add_subdirectory(docs)
endif()

# 打印信息
message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
message(STATUS "CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "CMAKE_CXX_COMPILER_VERSION: ${CMAKE_CXX_COMPILER_VERSION}")
message(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}")
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")